home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / quake.zip / HIPGRAPL.ZIP / HIPGREM.QC < prev    next >
Text File  |  1997-02-09  |  56KB  |  1,859 lines

  1. /*
  2. ==============================================================================
  3.  
  4. gremlin
  5.  
  6. ==============================================================================
  7. */
  8. $cd hipwork\models\grem
  9. $origin 0 0 23
  10. $scale 2
  11. $base grembase.asc
  12.  
  13. $skin grem
  14.  
  15. $frame stand1.asc stand2.asc stand3.asc stand4.asc stand5.asc stand6.asc
  16. $frame stand7.asc stand8.asc stand9.asc stand10.asc stand11.asc stand12.asc
  17. $frame stand13.asc stand14.asc stand15.asc stand16.asc stand17.asc
  18.  
  19. $frame walk1.asc walk2.asc walk3.asc walk4.asc walk5.asc walk6.asc
  20. $frame walk7.asc walk8.asc walk9.asc walk10.asc walk11.asc walk12.asc
  21.  
  22. $frame run1.asc run2.asc run3.asc run4.asc run5.asc run6.asc run7.asc run8.asc
  23. $frame run9.asc run10.asc run11.asc run12.asc run13.asc run14.asc run15.asc
  24.  
  25. $frame jump1.asc jump2.asc jump3.asc jump4.asc jump5.asc jump6.asc jump7.asc
  26. $frame jump8.asc jump9.asc jump10.asc jump11.asc jump12.asc jump13.asc jump14.asc
  27. $frame jump15.asc jump16.asc
  28.  
  29. $frame attk1.asc attk2.asc attk3.asc attk4.asc attk5.asc attk6.asc
  30. $frame attk7.asc attk8.asc attk9.asc attk10.asc attk11.asc
  31.  
  32. $frame maul1.asc maul2.asc maul3.asc maul4.asc maul5.asc maul6.asc
  33. $frame maul7.asc maul8.asc maul9.asc maul10.asc maul11.asc maul12.asc maul13.asc
  34.  
  35. $frame spawn1.asc spawn2.asc spawn3.asc spawn4.asc spawn5.asc spawn6.asc
  36.  
  37. $frame look1.asc look2.asc look3.asc look4.asc look5.asc look6.asc look7.asc
  38. $frame look8.asc look9.asc look10.asc
  39.  
  40. $frame pain1.asc pain2.asc pain3.asc pain4.asc
  41.  
  42. $frame death1.asc death2.asc death3.asc death4.asc death5.asc death6.asc death7.asc
  43. $frame death8.asc death9.asc death10.asc death11.asc death12.asc
  44.  
  45. $frame flip1.asc flip2.asc flip3.asc flip4.asc flip5.asc flip6.asc flip7.asc
  46. $frame flip8.asc
  47.  
  48. $frame lunge1.asc lunge2.asc lunge3.asc lunge4.asc lunge5.asc lunge6.asc lunge7.asc
  49. $frame lunge8.asc lunge9.asc lunge10.asc lunge11.asc
  50.  
  51. $frame gfire1.asc gfire2.asc gfire3.asc gfire4.asc gfire5.asc gfire6.asc
  52.  
  53. $frame glook1.asc glook2.asc glook3.asc glook4.asc glook5.asc glook6.asc glook7.asc
  54. $frame glook8.asc glook9.asc glook10.asc glook11.asc glook12.asc glook13.asc 
  55. $frame glook14.asc glook15.asc glook16.asc glook17.asc glook18.asc glook19.asc glook20.asc
  56.  
  57. $frame gpain1.asc gpain2.asc gpain3.asc
  58.  
  59. $frame grun1.asc grun2.asc grun3.asc grun4.asc grun5.asc grun6.asc grun7.asc
  60. $frame grun8.asc grun9.asc grun10.asc grun11.asc grun12.asc grun13.asc grun14.asc grun15.asc
  61.  
  62. //============================================================================
  63.  
  64. float NumGremlins;
  65. float NumSpawnGremlins;
  66.  
  67. /*
  68. ===========
  69. GremlinAttemptWeaponSteal
  70.  
  71. see if we can steal enemy's weapon
  72.  
  73. ============
  74. */
  75. entity()GremlinFindVictim;
  76. float() GremlinFindTarget;
  77.  
  78. float() GremlinAttemptWeaponSteal =
  79.    {
  80.    local vector delta;
  81.    local entity tempself;
  82.    local float best;
  83.    local entity victim;
  84.    local float amount;
  85.  
  86.    if (self.stoleweapon)
  87.       {
  88.       dprint("gremlin trying to steal a weapon again\n");
  89.       return FALSE;
  90.       }
  91.    if (!(self.enemy.flags & FL_CLIENT))
  92.       {
  93.       return FALSE;
  94.       }
  95.  
  96.    delta = (self.enemy.origin - self.origin);
  97.  
  98.    if (vlen(delta) > 100)
  99.       return FALSE;
  100.    if (random() < 0.5)
  101.       return FALSE;
  102.    //
  103.    // we are within range so lets go for it
  104.    //
  105.    victim = self.enemy;
  106.    best = victim.weapon;
  107.    if (best == IT_AXE || best == IT_SHOTGUN || best == IT_MJOLNIR)
  108.       return FALSE;
  109.    // take that weapon from the entity
  110.    victim.items = victim.items - (victim.items & best);
  111.    // give it to our gremlin
  112.    self.items = self.items | best;
  113.    self.weapon = best;
  114.    // take some ammo while we are at it
  115.    self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS ) );
  116.    if (best == IT_SUPER_SHOTGUN)
  117.       {
  118.       amount = victim.ammo_shells;
  119.       if (amount > 20)
  120.          amount = 20;
  121.       victim.ammo_shells = victim.ammo_shells - amount;
  122.       self.ammo_shells = self.ammo_shells + amount;
  123.         self.items = self.items | IT_SHELLS;
  124.       self.currentammo = self.ammo_shells;
  125.       sprint (victim, "Gremlin stole your Super Shotgun\n");
  126.       }
  127.    else if (best == IT_NAILGUN)
  128.       {
  129.       amount = victim.ammo_nails;
  130.       if (amount > 40)
  131.          amount = 40;
  132.       victim.ammo_nails = victim.ammo_nails - amount;
  133.       self.ammo_nails = self.ammo_nails + amount;
  134.       self.items = self.items | IT_NAILS;
  135.       self.currentammo = self.ammo_nails;
  136.       sprint (victim, "Gremlin stole your Nailgun\n");
  137.       }
  138.    else if (best == IT_SUPER_NAILGUN)
  139.       {
  140.       amount = victim.ammo_nails;
  141.       if (amount > 40)
  142.          amount = 40;
  143.       victim.ammo_nails = victim.ammo_nails - amount;
  144.       self.ammo_nails = self.ammo_nails + amount;
  145.       self.items = self.items | IT_NAILS;
  146.       self.currentammo = self.ammo_nails;
  147.       sprint (victim, "Gremlin stole your Super Nailgun\n");
  148.       }
  149.    else if (best == IT_GRENADE_LAUNCHER)
  150.       {
  151.       amount = victim.ammo_rockets;
  152.       if (amount > 5)
  153.          amount = 5;
  154.       victim.ammo_rockets = victim.ammo_rockets - amount;
  155.       self.ammo_rockets = self.ammo_rockets + amount;
  156.       self.items = self.items | IT_ROCKETS;
  157.       self.currentammo = self.ammo_rockets;
  158.       sprint (victim, "Gremlin stole your Grenade Launcher\n");
  159.       }
  160.    else if (best == IT_ROCKET_LAUNCHER)
  161.       {
  162.       amount = victim.ammo_rockets;
  163.       if (amount > 5)
  164.          amount = 5;
  165.       victim.ammo_rockets = victim.ammo_rockets - amount;
  166.       self.ammo_rockets = self.ammo_rockets + amount;
  167.       self.items = self.items | IT_ROCKETS;
  168.       self.currentammo = self.ammo_rockets;
  169.       sprint (victim, "Gremlin stole your Rocket Launcher\n");
  170.       }
  171.    else if (best == IT_LIGHTNING)
  172.       {
  173.       amount = victim.ammo_cells;
  174.       if (amount > 40)
  175.          amount = 40;
  176.       victim.ammo_cells = victim.ammo_cells - amount;
  177.       self.ammo_cells = self.ammo_cells + amount;
  178.       self.items = self.items | IT_CELLS;
  179.       self.currentammo = self.ammo_cells;
  180.       sprint (victim, "Gremlin stole your Lightning Gun\n");
  181.       }
  182.    else if (best == IT_LASER_CANNON)
  183.       {
  184.       amount = victim.ammo_cells;
  185.       if (amount > 40)
  186.          amount = 40;
  187.       victim.ammo_cells = victim.ammo_cells - amount;
  188.       self.ammo_cells = self.ammo_cells + amount;
  189.       self.items = self.items | IT_CELLS;
  190.       self.currentammo = self.ammo_cells;
  191.       sprint (victim, "Gremlin stole your Laser Cannon\n");
  192.       }
  193.    else if (best == IT_PROXIMITY_GUN)
  194.       {
  195.       amount = victim.ammo_rockets;
  196.       if (amount > 5)
  197.          amount = 5;
  198.       victim.ammo_rockets = victim.ammo_rockets - amount;
  199.       self.ammo_rockets = self.ammo_rockets + amount;
  200.       self.items = self.items | IT_ROCKETS;
  201.       self.currentammo = self.ammo_rockets;
  202.       sprint (victim, "Gremlin stole your Proximity Gun\n");
  203.       }
  204.    tempself = self;
  205.    self = victim;
  206.    self.weapon = W_BestWeapon ();
  207.    W_SetCurrentAmmo ();
  208.    self = tempself;
  209.  
  210.    // tag the gremlin as having stolen a weapon
  211.    self.stoleweapon = TRUE;
  212.    self.attack_finished = time;
  213.    // don't fire the first shot at the person we stole the weapon from
  214.    // all the time
  215.    if (random()>0.65)
  216.       self.lastvictim = victim;
  217.    else
  218.       self.lastvictim = self;
  219. //   self.attack_state = AS_STRAIGHT;
  220.    // find a recipient
  221.    victim = GremlinFindVictim();
  222.    if (victim != world)
  223.       {
  224.       self.enemy = victim;
  225.       FoundTarget();
  226.       self.attack_finished = time;
  227.       self.search_time = time + 1.0;
  228.       }
  229.  
  230.    return TRUE;
  231.    };
  232. //============================================================================
  233.  
  234. /*
  235. ===========
  236. GremlinFindTarget
  237.  
  238. gremlin is currently not attacking anything, so try to find a target
  239.  
  240. ============
  241. */
  242. float() GremlinFindTarget =
  243.    {
  244.    local entity   head;
  245.    local entity   gorge;
  246.    local float    dist;
  247.    local float    result;
  248.  
  249.    if ((self.stoleweapon==0) && time > self.wait)
  250.       {
  251.       self.wait = time + 1.0;
  252.       dist = 2000;
  253.       gorge = world;
  254.       head = nextent(world);
  255.       while (head!=world)
  256.          {
  257.          if ((head.health < 1) && (head.flags & (FL_MONSTER|FL_CLIENT)))
  258.             {
  259.             result = fabs(head.origin_z - self.origin_z);
  260.             if ((visible(head)) && (result<80) && (head.gorging == FALSE) && (visible_distance<dist))
  261.                {
  262.                dist = visible_distance;
  263.                gorge = head;
  264.                }
  265.             }
  266.          head = nextent(head);
  267.          }
  268.       if ((gorge != world) && (dist < (700*random())))
  269.          {
  270. //         dprint("starting to gorge on ");
  271. //         dprint(gorge.classname);
  272. //         dprint("\n");
  273.          self.oldenemy = self.enemy;
  274.          self.gorging = TRUE;
  275.          self.enemy = gorge;
  276.          self.search_time = time + 4.0;
  277.          FoundTarget();
  278.          return TRUE;
  279.          }
  280.       }
  281.    else if (self.stoleweapon)
  282.       {
  283.       head = GremlinFindVictim();
  284.       if (head != world)
  285.          {
  286.          self.enemy = head;
  287.          FoundTarget();
  288.          self.attack_finished = time;
  289.          self.search_time = time + 2.0;
  290.          return TRUE;
  291.          }
  292.       }
  293.    result = FindTarget();
  294.    self.search_time = time + 2.0;
  295.    return result;
  296.    };
  297. //============================================================================
  298. /*
  299. =============
  300. gremlin_walk
  301.  
  302. The monster is walking it's beat
  303. =============
  304. */
  305. void(float dist) gremlin_walk =
  306.    {
  307.     movedist = dist;
  308.  
  309.     // check for noticing a player
  310.    if (GremlinFindTarget ())
  311.         return;
  312.  
  313.     movetogoal (dist);
  314.    };
  315.  
  316. //============================================================================
  317.  
  318. /*
  319. =============
  320. gremlin_stand
  321.  
  322. The monster is staying in one place for a while, with slight angle turns
  323. =============
  324. */
  325. void() gremlin_stand =
  326.    {
  327.    if (FindTarget ())
  328.         return;
  329.  
  330.     if (time > self.pausetime)
  331.       {
  332.         self.th_walk ();
  333.         return;
  334.       }
  335.    };
  336.  
  337. //============================================================================
  338. float() GremlinCheckNoAmmo;
  339. void() gremlin_glook1;
  340. /*
  341. =============
  342. gremlin_run
  343.  
  344. The monster has an enemy it is trying to kill
  345. =============
  346. */
  347. void(float dist) gremlin_run =
  348.    {
  349.    local entity oldtarget;
  350.    local float r;
  351.    local vector d;
  352.  
  353.    if (self.watertype == CONTENT_LAVA)
  354.       {  // do damage
  355.       T_Damage (self, world, world, 2000);
  356.       }
  357.    movedist = dist;
  358.    if (self.stoleweapon)
  359.       self.frame = self.frame + $grun1.asc - $run1.asc;
  360.  
  361.    if (self.gorging)
  362.       {
  363.       traceline(self.origin, self.enemy.origin, TRUE, self);
  364.       if (trace_fraction != 1.0)
  365.          {
  366.          self.gorging = FALSE;
  367.          return;
  368.          }
  369.       if (!visible(self.enemy))
  370.          {
  371.          self.gorging = FALSE;
  372.          return;
  373.          }
  374.       r = vlen(self.enemy.origin - self.origin);
  375.       if (r < 130)
  376.          {
  377.          ai_face();
  378.          if (r < 45)
  379.             {
  380.             self.th_melee ();
  381.             self.attack_state = AS_STRAIGHT;
  382.             return;
  383.             }
  384.          else if (walkmove (self.angles_y, dist) == FALSE)
  385.             {
  386.             self.gorging = FALSE;
  387.             return;
  388.             }
  389.          return;
  390.          }
  391.       movetogoal (dist);      // done in C code...
  392.       }
  393.    else
  394.       {
  395.       if (random()>0.97)
  396.          {
  397.          if (GremlinFindTarget())
  398.             return;
  399.          }
  400.       // get away from player if we stole a weapon
  401.       if (self.stoleweapon)
  402.          {
  403.          if (self.enemy.health < 0 && self.enemy.classname == "player")
  404.             {
  405.             gremlin_glook1();
  406.             return;
  407.             }
  408.          if (!GremlinCheckNoAmmo())
  409.             {
  410.             if (self.t_length==1)
  411.                {
  412.                remove(self.trigger_field);
  413.                self.goalentity = self.enemy;
  414.                self.t_length = 0;
  415.                }
  416.             return;
  417.             }
  418.          r = vlen(self.enemy.origin - self.origin);
  419.          d = normalize(self.origin-self.enemy.origin);
  420.          if (self.t_length == 0)
  421.             {
  422.             if (r<150)
  423.                {
  424.                self.trigger_field = spawn();
  425.                setsize(self.trigger_field,'-1 -1 -1','1 1 1');
  426.                self.t_length = 1;
  427.                }
  428.             }
  429.          if (self.t_length==1)
  430.             {
  431.             if (r > 250)
  432.                {
  433.                remove(self.trigger_field);
  434.                self.goalentity = self.enemy;
  435.                self.t_length = 0;
  436. //               self.attack_state = AS_SLIDING;
  437.                }
  438.             else
  439.                {
  440.                if (r < 160)
  441.                   {
  442.                   local vector ang;
  443.                   local float done;
  444.                   local vector end;
  445.                   local float c;
  446.  
  447.                   ang = vectoangles(d);
  448.                   done = 0;
  449.                   c = 0;
  450.                   while (done == 0)
  451.                      {
  452.                      makevectors(ang);
  453.                      end = self.enemy.origin + v_forward * 350;
  454.                      traceline(self.enemy.origin,end,FALSE,self);
  455.                      if (trace_fraction == 1.0)
  456.                         {
  457.                         traceline(self.origin,end,FALSE,self);
  458.                         if (trace_fraction == 1.0)
  459.                            done = 1;
  460.                         }
  461.                      ang_y = anglemod(ang_y + 36);
  462.                      c = c + 1;
  463.                      if (c == 10)
  464.                         {
  465.                         done = 1;
  466.                         }
  467.                      }
  468.                   setorigin(self.trigger_field,end);
  469.                   }
  470.                self.goalentity = self.trigger_field;
  471.                self.ideal_yaw = vectoyaw(normalize(self.goalentity.origin-self.origin));
  472.                ChangeYaw ();
  473.                movetogoal (dist);      // done in C code...
  474.                self.nextthink = time + 0.1;
  475.                return;
  476.                }
  477.             }
  478.          }
  479.       ai_run(dist);
  480.       self.nextthink = time + 0.1;
  481.       }
  482.    };
  483.  
  484. //============================================================================
  485.  
  486. void()   Gremlin_JumpTouch;
  487. void()   Gremlin_FlipTouch;
  488. void(float side)  Gremlin_Melee;
  489. void(float side)  Gremlin_Gorge;
  490.  
  491. void()   gremlin_stand1  =[ $stand1.asc, gremlin_stand2  ] {gremlin_stand();self.nextthink = time + 0.2;};
  492. void()   gremlin_stand2  =[ $stand2.asc, gremlin_stand3  ] {gremlin_stand();self.nextthink = time + 0.2;};
  493. void()   gremlin_stand3  =[ $stand3.asc, gremlin_stand4  ] {gremlin_stand();self.nextthink = time + 0.2;};
  494. void()   gremlin_stand4  =[ $stand4.asc, gremlin_stand5  ] {gremlin_stand();self.nextthink = time + 0.2;};
  495. void()   gremlin_stand5  =[ $stand5.asc, gremlin_stand6  ] {gremlin_stand();self.nextthink = time + 0.2;};
  496. void()   gremlin_stand6  =[ $stand6.asc, gremlin_stand7  ] {gremlin_stand();self.nextthink = time + 0.2;};
  497. void()   gremlin_stand7  =[ $stand7.asc, gremlin_stand8  ] {gremlin_stand();self.nextthink = time + 0.2;};
  498. void()   gremlin_stand8  =[ $stand8.asc, gremlin_stand9  ] {gremlin_stand();self.nextthink = time + 0.2;};
  499. void()   gremlin_stand9  =[ $stand9.asc, gremlin_stand10 ] {gremlin_stand();self.nextthink = time + 0.2;};
  500. void()   gremlin_stand10 =[ $stand10.asc,   gremlin_stand11 ] {gremlin_stand();self.nextthink = time + 0.2;};
  501. void()   gremlin_stand11 =[ $stand11.asc,   gremlin_stand12 ] {gremlin_stand();self.nextthink = time + 0.2;};
  502. void()   gremlin_stand12 =[ $stand12.asc,   gremlin_stand13 ] {gremlin_stand();self.nextthink = time + 0.2;};
  503. void()   gremlin_stand13 =[ $stand13.asc,   gremlin_stand14 ] {gremlin_stand();self.nextthink = time + 0.2;};
  504. void()   gremlin_stand14 =[ $stand14.asc,   gremlin_stand15 ] {gremlin_stand();self.nextthink = time + 0.2;};
  505. void()   gremlin_stand15 =[ $stand15.asc,   gremlin_stand16 ] {gremlin_stand();self.nextthink = time + 0.2;};
  506. void()   gremlin_stand16 =[ $stand16.asc,   gremlin_stand17 ] {gremlin_stand();self.nextthink = time + 0.2;};
  507. void()   gremlin_stand17 =[ $stand17.asc,   gremlin_stand1  ] {gremlin_stand();self.nextthink = time + 0.2;};
  508.  
  509. void()   gremlin_walk1 =[ $walk1.asc,      gremlin_walk2 ] {
  510. if (random() < 0.1)
  511.     sound (self, CHAN_VOICE, "grem/idle.wav", 1, ATTN_IDLE);
  512. gremlin_walk(8);};
  513. void()   gremlin_walk2 =[ $walk2.asc,      gremlin_walk3 ] {gremlin_walk(8);};
  514. void()   gremlin_walk3 =[ $walk3.asc,      gremlin_walk4 ] {gremlin_walk(8);};
  515. void()   gremlin_walk4 =[ $walk4.asc,      gremlin_walk5 ] {gremlin_walk(8);};
  516. void()   gremlin_walk5 =[ $walk5.asc,      gremlin_walk6 ] {gremlin_walk(8);};
  517. void()   gremlin_walk6 =[ $walk6.asc,      gremlin_walk7 ] {gremlin_walk(8);};
  518. void()   gremlin_walk7 =[ $walk7.asc,      gremlin_walk8 ] {gremlin_walk(8);};
  519. void()   gremlin_walk8 =[ $walk8.asc,      gremlin_walk9 ] {gremlin_walk(8);};
  520. void()   gremlin_walk9 =[ $walk9.asc,      gremlin_walk10 ] {gremlin_walk(8);};
  521. void()   gremlin_walk10 =[ $walk10.asc,      gremlin_walk11 ] {gremlin_walk(8);};
  522. void()   gremlin_walk11 =[ $walk11.asc,      gremlin_walk12 ] {gremlin_walk(8);};
  523. void()   gremlin_walk12 =[ $walk12.asc,      gremlin_walk1 ] {gremlin_walk(8);};
  524.  
  525. void()   gremlin_run1 =[ $run1.asc,      gremlin_run2 ] {
  526. if (random() < 0.1)
  527.     sound (self, CHAN_VOICE, "grem/idle.wav", 1, ATTN_IDLE);
  528. gremlin_run(0);};
  529. void()   gremlin_run2 =[ $run2.asc,      gremlin_run3 ] {gremlin_run(8);};
  530. void()   gremlin_run3 =[ $run3.asc,      gremlin_run4 ] {gremlin_run(12);};
  531. void()   gremlin_run4 =[ $run4.asc,      gremlin_run5 ] {gremlin_run(16);};
  532. void()   gremlin_run5 =[ $run5.asc,      gremlin_run6 ] {gremlin_run(16);};
  533. void()   gremlin_run6 =[ $run6.asc,      gremlin_run7 ] {gremlin_run(12);};
  534. void()   gremlin_run7 =[ $run7.asc,      gremlin_run8 ] {gremlin_run(8);};
  535. void()   gremlin_run8 =[ $run8.asc,      gremlin_run9 ] {gremlin_run(0);};
  536. void()   gremlin_run9 =[ $run9.asc,      gremlin_run10 ] {gremlin_run(8);};
  537. void()   gremlin_run10 =[ $run10.asc,      gremlin_run11 ] {gremlin_run(12);};
  538. void()   gremlin_run11 =[ $run11.asc,      gremlin_run12 ] {gremlin_run(16);};
  539. void()   gremlin_run12 =[ $run12.asc,      gremlin_run1 ] {gremlin_run(16);};
  540. void()   gremlin_run13 =[ $run13.asc,      gremlin_run14 ] {gremlin_run(12);};
  541. void()   gremlin_run14 =[ $run14.asc,      gremlin_run15 ] {gremlin_run(8);};
  542. void()   gremlin_run15 =[ $run15.asc,      gremlin_run1 ] {gremlin_run(0);};
  543.  
  544. void()   gremlin_jump1   =[ $jump1.asc,     gremlin_jump2   ] {ai_face();};
  545. void()   gremlin_jump2   =[ $jump2.asc,     gremlin_jump3   ] {ai_face();};
  546. void()   gremlin_jump3   =[ $jump3.asc,     gremlin_jump4   ] {ai_face();};
  547. void()   gremlin_jump4   =[ $jump4.asc,     gremlin_jump5   ] {ai_face();};
  548. void()   gremlin_jump5   =[ $jump5.asc,     gremlin_jump6   ]
  549. {
  550.     ai_face();
  551.  
  552.    if (self.flags & FL_ONGROUND)
  553.       {
  554.       self.touch = Gremlin_JumpTouch;
  555.       makevectors (self.angles);
  556.       self.origin_z = self.origin_z + 1;
  557.       self.velocity = v_forward * 300 + '0 0 300';
  558.       self.flags = self.flags - FL_ONGROUND;
  559.       }
  560.    else
  561.       {
  562.       gremlin_run1();
  563.       }
  564. };
  565. void()   gremlin_jump6   =[ $jump6.asc,     gremlin_jump7   ] {};
  566. void()   gremlin_jump7   =[ $jump7.asc,     gremlin_jump8   ] {};
  567. void()   gremlin_jump8   =[ $jump8.asc,     gremlin_jump9   ] {};
  568. void()   gremlin_jump9   =[ $jump9.asc,     gremlin_jump10   ] {};
  569. void()   gremlin_jump10   =[ $jump10.asc,     gremlin_jump11   ] {};
  570. void()   gremlin_jump11   =[ $jump11.asc,     gremlin_jump1   ]
  571.    {
  572.    self.nextthink = time + 3;
  573.    // if three seconds pass, assume gremlin is stuck and jump again
  574.    };
  575.  
  576. void()   gremlin_jump12   =[ $jump12.asc,    gremlin_jump13  ] {};
  577. void()   gremlin_jump13   =[ $jump13.asc,    gremlin_jump14  ] {};
  578. void()   gremlin_jump14   =[ $jump14.asc,    gremlin_jump15  ] {};
  579. void()   gremlin_jump15   =[ $jump15.asc,    gremlin_jump16  ] {};
  580. void()   gremlin_jump16   =[ $jump16.asc,    gremlin_run1 ] {};
  581.  
  582. void()   gremlin_shot1 = [$gfire1.asc, gremlin_shot2   ] {self.effects = self.effects | EF_MUZZLEFLASH;};
  583. void()   gremlin_shot2 = [$gfire2.asc, gremlin_shot3   ] {};
  584. void()   gremlin_shot3 = [$gfire3.asc, gremlin_shot4   ] {};
  585. void()   gremlin_shot4 = [$gfire4.asc, gremlin_shot5   ] {};
  586. void()   gremlin_shot5 = [$gfire5.asc, gremlin_shot6   ] {};
  587. void()   gremlin_shot6 = [$gfire6.asc, gremlin_run1   ] {};
  588.  
  589.  
  590. //============================================================================
  591. void(float ox) Gremlin_FireNailGun;
  592.  
  593. void() gremlin_nail1   =[$gfire1.asc, gremlin_nail2  ]
  594.    {
  595.     self.effects = self.effects | EF_MUZZLEFLASH;
  596.    Gremlin_FireNailGun(4);
  597.    };
  598. void() gremlin_nail2   =[$gfire1.asc, gremlin_nail3  ]
  599.    {
  600.     self.effects = self.effects | EF_MUZZLEFLASH;
  601.    Gremlin_FireNailGun(4);
  602.    };
  603. void() gremlin_nail3   =[$gfire1.asc, gremlin_nail4  ]
  604.    {
  605.     self.effects = self.effects | EF_MUZZLEFLASH;
  606.    Gremlin_FireNailGun(4);
  607.    };
  608. void() gremlin_nail4   =[$gfire1.asc, gremlin_nail5  ]
  609.    {
  610.     self.effects = self.effects | EF_MUZZLEFLASH;
  611.    Gremlin_FireNailGun(4);
  612.    };
  613. void() gremlin_nail5   =[$gfire1.asc, gremlin_nail6  ]
  614.    {
  615.     self.effects = self.effects | EF_MUZZLEFLASH;
  616.    Gremlin_FireNailGun(4);
  617.    };
  618. void() gremlin_nail6   =[$gfire1.asc, gremlin_nail7  ]
  619.    {
  620.     self.effects = self.effects | EF_MUZZLEFLASH;
  621.    Gremlin_FireNailGun(4);
  622.    };
  623. void() gremlin_nail7 = [$gfire1.asc, gremlin_run1   ] {};
  624.  
  625.  
  626. void(float ox) Gremlin_FireLaserGun;
  627.  
  628. void() gremlin_laser1   =[$gfire1.asc, gremlin_laser2  ]
  629.    {
  630.     self.effects = self.effects | EF_MUZZLEFLASH;
  631.    Gremlin_FireLaserGun(4);
  632.    };
  633. void() gremlin_laser2   =[$gfire1.asc, gremlin_laser3  ]
  634.    {
  635.     self.effects = self.effects | EF_MUZZLEFLASH;
  636.    Gremlin_FireLaserGun(4);
  637.    };
  638. void() gremlin_laser3   =[$gfire1.asc, gremlin_laser4  ]
  639.    {
  640.     self.effects = self.effects | EF_MUZZLEFLASH;
  641.    Gremlin_FireLaserGun(4);
  642.    };
  643. void() gremlin_laser4   =[$gfire1.asc, gremlin_laser5  ]
  644.    {
  645.     self.effects = self.effects | EF_MUZZLEFLASH;
  646.    Gremlin_FireLaserGun(4);
  647.    };
  648. void() gremlin_laser5   =[$gfire1.asc, gremlin_laser6  ]
  649.    {
  650.     self.effects = self.effects | EF_MUZZLEFLASH;
  651.    Gremlin_FireLaserGun(4);
  652.    };
  653. void() gremlin_laser6   =[$gfire1.asc, gremlin_laser7  ]
  654.    {
  655.     self.effects = self.effects | EF_MUZZLEFLASH;
  656.    Gremlin_FireLaserGun(4);
  657.    };
  658. void() gremlin_laser7 = [$gfire1.asc, gremlin_run1   ] {};
  659.  
  660. //============================================================================
  661.  
  662. void() Gremlin_FireLightningGun;
  663. void() gremlin_light1   =[$gfire1.asc, gremlin_light2  ]
  664.    {
  665.    Gremlin_FireLightningGun();
  666.    };
  667. void() gremlin_light2 = [$gfire1.asc, gremlin_light3   ]
  668.    {
  669.    Gremlin_FireLightningGun();
  670.    };
  671. void() gremlin_light3   =[$gfire1.asc, gremlin_light4  ]
  672.    {
  673.    Gremlin_FireLightningGun();
  674.    };
  675. void() gremlin_light4 = [$gfire1.asc, gremlin_light5   ]
  676. {
  677.    Gremlin_FireLightningGun();
  678. };
  679. void() gremlin_light5 = [$gfire1.asc, gremlin_run1   ] {};
  680.  
  681. //============================================================================
  682.  
  683. void()   gremlin_rocket1 = [$gfire1.asc, gremlin_rocket2   ] {self.effects = self.effects | EF_MUZZLEFLASH;};
  684. void()   gremlin_rocket2 = [$gfire2.asc, gremlin_rocket3   ] {};
  685. void()   gremlin_rocket3 = [$gfire3.asc, gremlin_rocket4   ] {};
  686. void()   gremlin_rocket4 = [$gfire4.asc, gremlin_rocket5   ] {};
  687. void()   gremlin_rocket5 = [$gfire5.asc, gremlin_rocket6   ] {};
  688. void()   gremlin_rocket6 = [$gfire6.asc, gremlin_run1   ] {};
  689.  
  690. void()   gremlin_lunge1   =[ $lunge1.asc,     gremlin_lunge2   ] {ai_charge(0);};
  691. void()   gremlin_lunge2   =[ $lunge2.asc,     gremlin_lunge3   ] {ai_charge(0);};
  692. void()   gremlin_lunge3   =[ $lunge3.asc,     gremlin_lunge4   ] {ai_charge(0);};
  693. void()   gremlin_lunge4   =[ $lunge4.asc,     gremlin_lunge5   ] {ai_charge(0);};
  694. void()   gremlin_lunge5   =[ $lunge5.asc,     gremlin_lunge6   ] {ai_charge(0);};
  695. void()   gremlin_lunge6   =[ $lunge6.asc,     gremlin_lunge7   ] {ai_charge(0);};
  696. void()   gremlin_lunge7   =[ $lunge7.asc,     gremlin_lunge8   ] {ai_charge(15);};
  697. void()   gremlin_lunge8   =[ $lunge8.asc,     gremlin_lunge9   ] {ai_charge(0);Gremlin_Melee(0);};
  698. void()   gremlin_lunge9   =[ $lunge9.asc,     gremlin_lunge10] {ai_charge(0);};
  699. void()   gremlin_lunge10  =[ $lunge10.asc,    gremlin_lunge11] {ai_charge(0);};
  700. void()   gremlin_lunge11  =[ $lunge11.asc,    gremlin_run1] {ai_charge(0);};
  701.  
  702. void()   gremlin_claw1   =[ $attk1.asc,     gremlin_claw2   ] {ai_charge(0);};
  703. void()   gremlin_claw2   =[ $attk2.asc,     gremlin_claw3   ] {ai_charge(0);};
  704. void()   gremlin_claw3   =[ $attk3.asc,     gremlin_claw4   ] {ai_charge(0);};
  705. void()   gremlin_claw4   =[ $attk4.asc,     gremlin_claw5   ] {ai_charge(0);};
  706. void()   gremlin_claw5   =[ $attk5.asc,     gremlin_claw6   ] {ai_charge(0);};
  707. void()   gremlin_claw6   =[ $attk6.asc,     gremlin_claw7   ] {ai_charge(0);Gremlin_Melee(200);};
  708. void()   gremlin_claw7   =[ $attk7.asc,     gremlin_claw8   ] {ai_charge(15);};
  709. void()   gremlin_claw8   =[ $attk8.asc,     gremlin_claw9   ] {ai_charge(0);};
  710. void()   gremlin_claw9   =[ $attk9.asc,     gremlin_claw10] {ai_charge(0);};
  711. void()   gremlin_claw10  =[ $attk10.asc,    gremlin_claw11] {ai_charge(0);};
  712. void()   gremlin_claw11  =[ $attk11.asc,    gremlin_run1] {ai_charge(0);};
  713.  
  714. void()   gremlin_gorge1   =[ $maul1.asc,     gremlin_gorge2] {ai_charge(1);};
  715. void()   gremlin_gorge2   =[ $maul2.asc,     gremlin_gorge3] {ai_charge(1);};
  716. void()   gremlin_gorge3   =[ $maul3.asc,     gremlin_gorge4] {ai_charge(2);};
  717. void()   gremlin_gorge4   =[ $maul4.asc,     gremlin_gorge5] {ai_charge(0);};
  718. void()   gremlin_gorge5   =[ $maul5.asc,     gremlin_gorge6] {ai_charge(0);};
  719. void()   gremlin_gorge6   =[ $maul6.asc,     gremlin_gorge7] {ai_charge(0);Gremlin_Gorge(200);};
  720. void()   gremlin_gorge7   =[ $maul7.asc,     gremlin_gorge8] {ai_charge(0);};
  721. void()   gremlin_gorge8   =[ $maul8.asc,     gremlin_gorge9] {ai_charge(0);Gremlin_Gorge(-200);};
  722. void()   gremlin_gorge9   =[ $maul9.asc,     gremlin_gorge10] {ai_charge(0);};
  723. void()   gremlin_gorge10   =[ $maul10.asc,     gremlin_gorge11] {ai_charge(0);};
  724. void()   gremlin_gorge11   =[ $maul11.asc,     gremlin_gorge12] {ai_charge(0);};
  725. void()   gremlin_gorge12   =[ $maul12.asc,     gremlin_gorge13] {ai_charge(0);};
  726. void()   gremlin_gorge13   =[ $maul13.asc,     gremlin_gorge1] {ai_charge(0);};
  727.  
  728. void()   gremlin_look1   =[ $look1.asc,     gremlin_look2] {self.nextthink = time + 0.2;};
  729. void()   gremlin_look2   =[ $look2.asc,     gremlin_look3] {self.nextthink = time + 0.2;};
  730. void()   gremlin_look3   =[ $look3.asc,     gremlin_look4] {self.nextthink = time + 0.2;};
  731. void()   gremlin_look4   =[ $look4.asc,     gremlin_look5] {self.nextthink = time + 0.2;};
  732. void()   gremlin_look5   =[ $look5.asc,     gremlin_look6] {self.nextthink = time + 0.2;};
  733. void()   gremlin_look6   =[ $look6.asc,     gremlin_look7] {self.nextthink = time + 0.2;};
  734. void()   gremlin_look7   =[ $look7.asc,     gremlin_look8] {self.nextthink = time + 0.2;};
  735. void()   gremlin_look8   =[ $look8.asc,     gremlin_look9] {self.nextthink = time + 0.2;};
  736. void()   gremlin_look9   =[ $look9.asc,     gremlin_run1]
  737.    {
  738.    if (self.oldenemy.health > 0)
  739.       {
  740.       self.enemy = self.oldenemy;
  741.       HuntTarget ();
  742.       }
  743.    else
  744.       {
  745.       if (self.movetarget)
  746.          self.th_walk ();
  747.       else
  748.          self.th_stand ();
  749.       }
  750.    };
  751.  
  752.  
  753. void() GremlinDropBackpack;
  754. void()   gremlin_glook1   =[ $glook1.asc,     gremlin_glook2] {};
  755. void()   gremlin_glook2   =[ $glook2.asc,     gremlin_glook3] {};
  756. void()   gremlin_glook3   =[ $glook3.asc,     gremlin_glook4] {};
  757. void()   gremlin_glook4   =[ $glook4.asc,     gremlin_glook5] {};
  758. void()   gremlin_glook5   =[ $glook5.asc,     gremlin_glook6] {};
  759. void()   gremlin_glook6   =[ $glook6.asc,     gremlin_glook7] {};
  760. void()   gremlin_glook7   =[ $glook7.asc,     gremlin_glook8] {};
  761. void()   gremlin_glook8   =[ $glook8.asc,     gremlin_glook9] {};
  762. void()   gremlin_glook9   =[ $glook9.asc,     gremlin_glook10] {};
  763. void()   gremlin_glook10   =[ $glook10.asc,     gremlin_glook11] {};
  764. void()   gremlin_glook11   =[ $glook11.asc,     gremlin_glook12] {};
  765. void()   gremlin_glook12   =[ $glook12.asc,     gremlin_glook13] {};
  766. void()   gremlin_glook13   =[ $glook13.asc,     gremlin_glook14] {};
  767. void()   gremlin_glook14   =[ $glook14.asc,     gremlin_glook15] {};
  768. void()   gremlin_glook15   =[ $glook15.asc,     gremlin_glook16] {};
  769. void()   gremlin_glook16   =[ $glook16.asc,     gremlin_glook17] {};
  770. void()   gremlin_glook17   =[ $glook17.asc,     gremlin_glook18] {};
  771. void()   gremlin_glook18   =[ $glook18.asc,     gremlin_glook19] {};
  772. void()   gremlin_glook19   =[ $glook19.asc,     gremlin_glook20] {};
  773. void()   gremlin_glook20   =[ $glook20.asc,     gremlin_glook20]
  774.    {
  775.    GremlinDropBackpack();
  776.    self.stoleweapon = FALSE;
  777.    if (self.oldenemy.health > 0)
  778.       {
  779.       self.enemy = self.oldenemy;
  780.       HuntTarget ();
  781.       }
  782.    else
  783.       {
  784.       if (self.movetarget)
  785.          self.th_walk ();
  786.       else
  787.          self.th_stand ();
  788.       }
  789.    };
  790.  
  791. void()   gremlin_pain1   =[ $pain1.asc,     gremlin_pain2   ] {ai_back(4);};
  792. void()   gremlin_pain2   =[ $pain2.asc,     gremlin_pain3   ] {ai_back(4);};
  793. void()   gremlin_pain3   =[ $pain3.asc,     gremlin_pain4   ] {ai_back(2);};
  794. void()   gremlin_pain4   =[ $pain4.asc,     gremlin_run1 ] {};
  795.  
  796. void()   gremlin_gunpain1   =[ $gpain1.asc,     gremlin_gunpain2   ] {ai_back(4);};
  797. void()   gremlin_gunpain2   =[ $gpain2.asc,     gremlin_gunpain3   ] {ai_back(2);};
  798. void()   gremlin_gunpain3   =[ $gpain3.asc,     gremlin_run1 ] {};
  799.  
  800. void(entity attacker, float damage) gremlin_pain =
  801. {
  802.    local float r;
  803.  
  804.    if (random()<0.8)
  805.       {
  806.       self.gorging = FALSE;
  807.       self.enemy = attacker;
  808.       FoundTarget();
  809.       }
  810.    if (self.touch == Gremlin_JumpTouch)
  811.         return;
  812.  
  813.     if (self.pain_finished > time)
  814.         return;
  815.  
  816.     self.pain_finished = time + 1;
  817. //   if (random()<0.5)
  818. //      sound (self, CHAN_VOICE, "grem/pain2.wav", 1, ATTN_NORM);
  819. //   else
  820.    r = random();
  821.    if (r<0.33)
  822.       sound (self, CHAN_VOICE, "grem/pain1.wav", 1, ATTN_NORM);
  823.    else if (r<0.66)
  824.       sound (self, CHAN_VOICE, "grem/pain2.wav", 1, ATTN_NORM);
  825.    else
  826.       sound (self, CHAN_VOICE, "grem/pain3.wav", 1, ATTN_NORM);
  827.  
  828.    if (self.stoleweapon)
  829.       {
  830.       gremlin_gunpain1 ();
  831.       }
  832.    else
  833.       {
  834.       gremlin_pain1 ();
  835.       }
  836. };
  837.  
  838. void()   gremlin_spawn1 =[ $spawn1.asc,      gremlin_spawn2 ] {self.nextthink = time + 0.3;
  839.    self.th_pain = SUB_Null;
  840. //    sound (self, CHAN_VOICE, "grem/idle.wav", 1, ATTN_IDLE);
  841. };
  842. void()   gremlin_spawn2 =[ $spawn2.asc,      gremlin_spawn3 ] {self.nextthink = time + 0.3;};
  843. void()   gremlin_spawn3 =[ $spawn3.asc,      gremlin_spawn4 ] {self.nextthink = time + 0.3;};
  844. void()   gremlin_spawn4 =[ $spawn4.asc,      gremlin_spawn5 ] {self.nextthink = time + 0.3;};
  845. void()   gremlin_spawn5 =[ $spawn5.asc,      gremlin_spawn6 ] {self.nextthink = time + 0.3;};
  846. void()   gremlin_spawn6 =[ $spawn6.asc,      gremlin_run1 ] {
  847.    self.th_pain = gremlin_pain;
  848. };
  849.  
  850.  
  851. void()   gremlin_die1    =[ $death1.asc,    gremlin_die2 ] {
  852. sound (self, CHAN_VOICE, "grem/death.wav", 1, ATTN_NORM);};
  853. void()   gremlin_die2    =[ $death2.asc,    gremlin_die3 ] {ai_forward(2);};
  854. void()   gremlin_die3    =[ $death3.asc,    gremlin_die4 ] {ai_forward(1);};
  855. void()   gremlin_die4    =[ $death4.asc,    gremlin_die5 ] {ai_forward(2);};
  856. void()   gremlin_die5    =[ $death5.asc,    gremlin_die6 ] {ai_forward(1);};
  857. void()   gremlin_die6    =[ $death6.asc,    gremlin_die7 ]
  858. {self.solid = SOLID_NOT;};
  859. void()   gremlin_die7    =[ $death7.asc,    gremlin_die8 ] {ai_forward(2);};
  860. void()   gremlin_die8    =[ $death8.asc,    gremlin_die9 ] {ai_forward(1);};
  861. void()   gremlin_die9    =[ $death9.asc,    gremlin_die10 ] {ai_forward(2);};
  862. void()   gremlin_die10    =[ $death10.asc,    gremlin_die11 ] {ai_forward(1);};
  863. void()   gremlin_die11    =[ $death11.asc,    gremlin_die12 ] {ai_forward(2);};
  864. void()   gremlin_die12    =[ $death12.asc,    gremlin_die12 ] {};
  865.  
  866. void() gremlin_gib=
  867.    {
  868.    sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  869.    ThrowHead ("progs/h_grem.mdl", -35);
  870.    ThrowGib ("progs/gib1.mdl", -35);
  871.    ThrowGib ("progs/gib1.mdl", -35);
  872.    ThrowGib ("progs/gib1.mdl", -35);
  873.    };
  874.  
  875. void()   gremlin_flip1    =[ $flip1.asc,    gremlin_flip2 ]
  876.    {
  877.    ai_face();
  878.     makevectors (self.angles);
  879.    self.origin_z = self.origin_z + 1;
  880.    self.velocity = '0 0 350' - (v_forward * 200);
  881.     if (self.flags & FL_ONGROUND)
  882.         self.flags = self.flags - FL_ONGROUND;
  883.    sound (self, CHAN_VOICE, "grem/death.wav", 1, ATTN_NORM);
  884.    };
  885. void()   gremlin_flip2    =[ $flip2.asc,    gremlin_flip3 ] {ai_face();};
  886. void()   gremlin_flip3    =[ $flip3.asc,    gremlin_flip4 ] {};
  887. void()   gremlin_flip4    =[ $flip4.asc,    gremlin_flip5 ] {};
  888. void()   gremlin_flip5    =[ $flip5.asc,    gremlin_flip6 ] {};
  889. void()   gremlin_flip6    =[ $flip6.asc,    gremlin_flip7 ] {self.touch = Gremlin_FlipTouch;};
  890. void()   gremlin_flip7    =[ $flip7.asc,    gremlin_gib ]
  891.    {
  892.    self.nextthink = time + 3;
  893.    // if three seconds pass, assume gremlin is stuck and jump again
  894.    };
  895. void()   gremlin_flip8    =[ $flip8.asc,    gremlin_flip8 ]
  896.    {
  897.    self.solid = SOLID_NOT;
  898.    };
  899.  
  900. /*
  901. ===============
  902. GremlinDropBackpack
  903. ===============
  904. */
  905. void() GremlinDropBackpack =
  906. {
  907.     local entity    item;
  908.  
  909.     item = spawn();
  910.     item.origin = self.origin - '0 0 24';
  911.  
  912.    self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS ) );
  913.    item.items = self.items;
  914.  
  915.    if (item.items & IT_AXE)
  916.         item.netname = "Axe";
  917.    else if (item.items & IT_SHOTGUN)
  918.         item.netname = "Shotgun";
  919.    else if (item.items & IT_SUPER_SHOTGUN)
  920.         item.netname = "Double-barrelled Shotgun";
  921.    else if (item.items & IT_NAILGUN)
  922.         item.netname = "Nailgun";
  923.    else if (item.items & IT_SUPER_NAILGUN)
  924.         item.netname = "Super Nailgun";
  925.    else if (item.items & IT_GRENADE_LAUNCHER)
  926.         item.netname = "Grenade Launcher";
  927.    else if (item.items & IT_ROCKET_LAUNCHER)
  928.         item.netname = "Rocket Launcher";
  929.    else if (item.items & IT_LIGHTNING)
  930.         item.netname = "Thunderbolt";
  931.    else if (item.items & IT_LASER_CANNON)
  932.       item.netname = "Laser Cannon";
  933.    else if (item.items & IT_PROXIMITY_GUN)
  934.       item.netname = "Proximity Gun";
  935.    else if (item.items & IT_MJOLNIR)
  936.       item.netname = "Mjolnir";
  937.    else
  938.         item.netname = "";
  939.  
  940.    item.ammo_shells = self.ammo_shells;
  941.     item.ammo_nails = self.ammo_nails;
  942.     item.ammo_rockets = self.ammo_rockets;
  943.     item.ammo_cells = self.ammo_cells;
  944.    if (item.ammo_shells < 0) item.ammo_shells = 0;
  945.    if (item.ammo_nails < 0) item.ammo_nails = 0;
  946.    if (item.ammo_rockets < 0) item.ammo_rockets = 0;
  947.    if (item.ammo_cells < 0) item.ammo_cells = 0;
  948.  
  949.     item.velocity_z = 300;
  950.     item.velocity_x = -100 + (random() * 200);
  951.     item.velocity_y = -100 + (random() * 200);
  952.  
  953.     item.flags = FL_ITEM;
  954.     item.solid = SOLID_TRIGGER;
  955.     item.movetype = MOVETYPE_TOSS;
  956.     setmodel (item, "progs/backpack.mdl");
  957.     setsize (item, '-16 -16 0', '16 16 56');
  958.     item.touch = BackpackTouch;
  959.  
  960.     item.nextthink = time + 120;    // remove after 2 minutes
  961.     item.think = SUB_Remove;
  962. };
  963.  
  964. void() gremlin_die =
  965. {
  966.    local vector   vec;
  967.     local float        dot;
  968.  
  969. // check for gib
  970.    if (self.items & (IT_SUPER_SHOTGUN|IT_NAILGUN|IT_SUPER_NAILGUN|IT_GRENADE_LAUNCHER|IT_ROCKET_LAUNCHER|IT_LIGHTNING|IT_LASER_CANNON|IT_PROXIMITY_GUN))
  971.       {
  972.       GremlinDropBackpack();
  973.       self.stoleweapon = FALSE;
  974.       }
  975.  
  976.    makevectors (self.angles);
  977.    vec = normalize (damage_attacker.origin - self.origin);
  978.     dot = vec * v_forward;
  979.  
  980.    if (self.health < -35)
  981.       {
  982.         sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  983.       ThrowHead ("progs/h_grem.mdl", self.health);
  984.         ThrowGib ("progs/gib1.mdl", self.health);
  985.         ThrowGib ("progs/gib1.mdl", self.health);
  986.         ThrowGib ("progs/gib1.mdl", self.health);
  987.         return;
  988.       }
  989.    else if (dot>0.7 && (random()<0.5) && (self.flags & FL_ONGROUND))
  990.       {
  991.       gremlin_flip1();
  992.       return;
  993.       }
  994. // regular death
  995.    gremlin_die1 ();
  996. };
  997.  
  998.  
  999. float() GremlinWeaponAttack;
  1000. void() Gremlin_MeleeAttack =
  1001.    {
  1002.    local float num;
  1003.    if (self.gorging)
  1004.       {
  1005.       gremlin_gorge1();
  1006.       }
  1007.    else
  1008.       {
  1009.       if (self.stoleweapon == 1)
  1010.          {
  1011.          objerror("gremlin meleeing with stolen weapon");
  1012.          }
  1013.       else if ((self.enemy.flags & FL_CLIENT) && random() < 0.4)
  1014.          {
  1015.          if (GremlinAttemptWeaponSteal())
  1016.             return;
  1017.          }
  1018.       num = random();
  1019.       if (num<0.3)
  1020.          {
  1021.          gremlin_claw1 ();
  1022.          }
  1023.       else if (num < 0.6)
  1024.          {
  1025.          gremlin_lunge1 ();
  1026.          }
  1027.       else
  1028.          {
  1029.          gremlin_claw1 ();
  1030.          }
  1031.       }
  1032.    };
  1033.  
  1034. /*
  1035. ============
  1036. gremlin_recoil
  1037. ============
  1038. */
  1039. /*
  1040. void() gremlin_recoil =
  1041.    {
  1042.    self.nextthink = time + 0.1;
  1043.    self.flags = self.flags - FL_ONGROUND;
  1044.    if (vlen(self.velocity)<2)
  1045.       {
  1046.       self.movetype = self.spawnsolidtype;
  1047.       self.think = self.spawnthink;
  1048.       }
  1049.    };
  1050. */
  1051. /*
  1052. ============
  1053. GremlinRecoil
  1054. ============
  1055. */
  1056. /*
  1057. void(vector dir, float mag) GremlinRecoil =
  1058.    {
  1059.    self.spawnsolidtype = self.movetype;
  1060.    self.movetype = MOVETYPE_BOUNCE;
  1061.    self.spawnthink = self.think;
  1062.    self.think = gremlin_recoil;
  1063.    self.nextthink = time;
  1064.    self.velocity = mag * dir;
  1065.    self.velocity_z = self.velocity_z + 100;
  1066.    self.flags = self.flags - FL_ONGROUND;
  1067.    };
  1068. */
  1069.  
  1070. /*
  1071. ============
  1072. GremlinCheckNoAmmo
  1073.  
  1074. attack with a weapon
  1075. ============
  1076. */
  1077. float() GremlinCheckNoAmmo =
  1078.    {
  1079.     if (self.currentammo > 0)
  1080.         return TRUE;
  1081.    else
  1082.       {
  1083.       self.stoleweapon = FALSE;
  1084.       return FALSE;
  1085.       }
  1086.    };
  1087.  
  1088. /*
  1089. ============
  1090. GremlinFindVictim
  1091.  
  1092. find a victim to shoot at
  1093. ============
  1094. */
  1095. entity() GremlinFindVictim =
  1096.    {
  1097.    local entity head;
  1098.    local entity selected;
  1099.    local float dist;
  1100.    local float head_dist;
  1101.    local float decision;
  1102.  
  1103.    self.search_time = time + 1.0;
  1104. // look in our immediate vicinity
  1105.  
  1106.    selected = world;
  1107.    dist = 1000;
  1108.    head = findradius(self.origin, 1000);
  1109.    while(head)
  1110.       {
  1111.       if(!(head.flags & FL_NOTARGET) && ((head.flags & FL_MONSTER) || (head.flags & FL_CLIENT)))
  1112.          {
  1113.          if (visible(head) && (head.health > 0) && (head !=self))
  1114.             {
  1115.             head_dist = vlen(head.origin-self.origin);
  1116.             if (head == self.lastvictim)
  1117.                head_dist = head_dist * 2;
  1118.             if (head.flags & FL_CLIENT)
  1119.                head_dist = head_dist / 1.5;
  1120.             if (head.classname == self.classname)
  1121.                head_dist = head_dist * 1.5;
  1122.             if (head_dist < dist)
  1123.                {
  1124.                selected = head;
  1125.                dist = head_dist;
  1126.                }
  1127.             }
  1128.          }
  1129.       head = head.chain;
  1130.       }
  1131.    self.lastvictim = selected;
  1132.  
  1133.    return selected;
  1134.    };
  1135.  
  1136. /*
  1137. ============
  1138. Gremlin_FireRocket
  1139.  
  1140. fire a rocket
  1141. ============
  1142. */
  1143. void() Gremlin_FireRocket =
  1144. {
  1145.     local    entity missile, mpuff;
  1146.    local vector dir;
  1147.  
  1148.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1149.    self.effects = self.effects | EF_MUZZLEFLASH;
  1150.  
  1151.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  1152.  
  1153.     self.punchangle_x = -2;
  1154.  
  1155.     missile = spawn ();
  1156.     missile.owner = self;
  1157.     missile.movetype = MOVETYPE_FLYMISSILE;
  1158.     missile.solid = SOLID_BBOX;
  1159.     missile.classname = "missile";
  1160.  
  1161. // set missile speed
  1162.  
  1163.    dir = normalize(self.enemy.origin - self.origin);
  1164.    self.v_angle = vectoangles(dir);
  1165.    makevectors(self.v_angle);
  1166.    dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
  1167.    missile.velocity = normalize(dir);
  1168.    missile.velocity = missile.velocity * 1000;
  1169.     missile.angles = vectoangles(missile.velocity);
  1170.  
  1171.     missile.touch = T_MissileTouch;
  1172.  
  1173. // set missile duration
  1174.     missile.nextthink = time + 5;
  1175.     missile.think = SUB_Remove;
  1176.  
  1177.     setmodel (missile, "progs/missile.mdl");
  1178.     setsize (missile, '0 0 0', '0 0 0');
  1179.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  1180. //   GremlinRecoil(dir,-1000);
  1181. };
  1182.  
  1183. /*
  1184. ============
  1185. Gremlin_FireNailGun
  1186.  
  1187. fire a nailgun
  1188. ============
  1189. */
  1190. void(float ox) Gremlin_FireNailGun =
  1191. {
  1192.    local vector dir;
  1193.  
  1194.    self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  1195.    self.effects = self.effects | EF_MUZZLEFLASH;
  1196.  
  1197.    sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1198.    dir = normalize(self.enemy.origin - self.origin);
  1199.    self.v_angle = vectoangles(dir);
  1200.    makevectors(self.v_angle);
  1201.    dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
  1202.    dir = normalize(dir);
  1203.    launch_spike (self.origin + '0 0 16', dir);
  1204. };
  1205.  
  1206. /*
  1207. ============
  1208. Gremlin_FireLaserGun
  1209.  
  1210. fire a laser cannon
  1211. ============
  1212. */
  1213. void(float ox) Gremlin_FireLaserGun =
  1214. {
  1215.    local vector dir;
  1216.  
  1217.    self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  1218.    self.effects = self.effects | EF_MUZZLEFLASH;
  1219.  
  1220.    sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  1221.    dir = normalize(self.enemy.origin - self.origin);
  1222.    self.v_angle = vectoangles(dir);
  1223.    makevectors(self.v_angle);
  1224.    dir = dir + crandom()* 0.1 * v_right + crandom()* 0.1 *v_up;
  1225.    dir = normalize(dir);
  1226.    HIP_LaunchLaser(self.origin + '0 0 16', dir, 0);
  1227. };
  1228.  
  1229. /*
  1230. ============
  1231. Gremlin_FireShotGun
  1232.  
  1233. fire a shotgun
  1234. ============
  1235. */
  1236. void() Gremlin_FireShotGun =
  1237. {
  1238.    local vector dir;
  1239.  
  1240.    self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1241.    self.effects = self.effects | EF_MUZZLEFLASH;
  1242.  
  1243.    sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
  1244.    dir = normalize(self.enemy.origin - self.origin);
  1245.    self.v_angle = vectoangles(dir);
  1246.    makevectors(self.v_angle);
  1247.    dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
  1248.    dir = normalize(dir);
  1249.    self.v_angle = vectoangles(dir);
  1250.    FireBullets (6, dir, '0.04 0.04 0');
  1251. };
  1252.  
  1253. /*
  1254. ============
  1255. Gremlin_FireSuperShotGun
  1256.  
  1257. fire a shotgun
  1258. ============
  1259. */
  1260. void() Gremlin_FireSuperShotGun =
  1261. {
  1262.    local vector dir;
  1263.  
  1264.    self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  1265.    self.effects = self.effects | EF_MUZZLEFLASH;
  1266.  
  1267.    sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
  1268.    dir = normalize(self.enemy.origin - self.origin);
  1269.    self.v_angle = vectoangles(dir);
  1270.    makevectors(self.v_angle);
  1271.    dir = dir + crandom()* 0.3 *v_right + crandom()* 0.3 *v_up;
  1272.    dir = normalize(dir);
  1273.    self.v_angle = vectoangles(dir);
  1274.    FireBullets (14, dir, '0.14 0.08 0');
  1275. };
  1276.  
  1277. /*
  1278. ============
  1279. Gremlin_FireLightningGun
  1280.  
  1281. fire lightning gun
  1282. ============
  1283. */
  1284. void() Gremlin_FireLightningGun =
  1285.    {
  1286.     local    vector    org, dir;
  1287.    local float cells;
  1288.  
  1289. // explode if under water
  1290.    if (self.watertype <= CONTENT_WATER)
  1291.     {
  1292.         cells = self.ammo_cells;
  1293.         self.ammo_cells = 0;
  1294.       discharged = 1;
  1295.         T_RadiusDamage (self, self, 35*cells, world);
  1296.       discharged = 0;
  1297. //      W_SetCurrentAmmo ();
  1298.         return;
  1299.     }
  1300.  
  1301.    self.effects = self.effects | EF_MUZZLEFLASH;
  1302.  
  1303.     ai_face ();
  1304.  
  1305.    self.currentammo = self.ammo_cells = self.ammo_cells - 2;
  1306.    org = self.origin + '0 0 16';
  1307.  
  1308.     dir = self.enemy.origin + '0 0 16' - org;
  1309.     dir = normalize (dir);
  1310.    dir = normalize(self.enemy.origin - self.origin);
  1311.    self.v_angle = vectoangles(dir);
  1312.    makevectors(self.v_angle);
  1313.    dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
  1314.    dir = normalize(dir);
  1315.  
  1316.     traceline (org, self.origin + dir*600, TRUE, self);
  1317.  
  1318.    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1319.    WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  1320.     WriteEntity (MSG_BROADCAST, self);
  1321.     WriteCoord (MSG_BROADCAST, org_x);
  1322.     WriteCoord (MSG_BROADCAST, org_y);
  1323.     WriteCoord (MSG_BROADCAST, org_z);
  1324.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  1325.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  1326.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  1327.  
  1328.    LightningDamage (org, trace_endpos+(dir*4), self, 30);
  1329. };
  1330.  
  1331. /*
  1332. ================
  1333. GremlinFireProximityGrenade
  1334. ================
  1335. */
  1336. void() GremlinFireProximityGrenade =
  1337. {
  1338.    local entity missile;
  1339.    local vector dir;
  1340.  
  1341.    NumProximityGrenades = NumProximityGrenades + 1;
  1342.    self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1343.  
  1344.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  1345.  
  1346.     missile = spawn ();
  1347.    missile.owner = self;
  1348.    missile.lastvictim = self;
  1349.    missile.movetype = MOVETYPE_TOSS;
  1350.     missile.solid = SOLID_BBOX;
  1351.    missile.classname = "proximity_grenade";
  1352.    missile.takedamage = DAMAGE_NO;
  1353.    missile.health = 5;
  1354.    missile.state = 0;
  1355.  
  1356. // set missile speed
  1357.  
  1358.    dir = normalize(self.enemy.origin - self.origin);
  1359.    self.v_angle = vectoangles(dir);
  1360.    makevectors(self.v_angle);
  1361.    dir = dir + crandom()* 0.1 *v_right + crandom()* 0.1 *v_up;
  1362.    dir = normalize(dir);
  1363.    missile.velocity = dir * 600;
  1364.     missile.velocity_z = 200;
  1365.  
  1366.    missile.avelocity = '100 600 100';
  1367.  
  1368.     missile.angles = vectoangles(missile.velocity);
  1369.  
  1370.    missile.touch = ProximityGrenadeTouch;
  1371.  
  1372. // set missile duration
  1373.    missile.nextthink = time + 2;
  1374.    missile.delay = time + 15 + (10*random());
  1375.    missile.think = ProximityBomb;
  1376.    missile.th_die = ProximityGrenadeExplode;
  1377.  
  1378.    setmodel (missile, "progs/proxbomb.mdl");
  1379.    setorigin (missile, self.origin);
  1380.    setsize (missile, '-1 -1 -1', '1 1 1');
  1381. };
  1382.  
  1383. /*
  1384. ============
  1385. GremlinWeaponAttack
  1386.  
  1387. attack with a weapon
  1388. ============
  1389. */
  1390. void()   gremlin_shot1;
  1391. void()   gremlin_nail1;
  1392. void()   gremlin_light1;
  1393. void()   gremlin_rocket1;
  1394.  
  1395. float() GremlinWeaponAttack =
  1396.    {
  1397.     local    float    r;
  1398.    local entity targ;
  1399.    local vector vec;
  1400.  
  1401.  
  1402.    if (!GremlinCheckNoAmmo ())
  1403.       return FALSE;
  1404.  
  1405.    self.show_hostile = time + 1; // wake monsters up
  1406.  
  1407.    if (self.weapon == IT_SHOTGUN)
  1408.       {
  1409.       gremlin_shot1 ();
  1410.       Gremlin_FireShotGun();
  1411.       SUB_AttackFinished(1);
  1412.       }
  1413.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1414.       {
  1415.       gremlin_shot1 ();
  1416.       Gremlin_FireSuperShotGun();
  1417.       SUB_AttackFinished(1);
  1418.       }
  1419.     else if (self.weapon == IT_NAILGUN)
  1420.       {
  1421.       gremlin_nail3 ();
  1422.       SUB_AttackFinished(1);
  1423.       }
  1424.     else if (self.weapon == IT_SUPER_NAILGUN)
  1425.       {
  1426.       gremlin_nail3 ();
  1427.       SUB_AttackFinished(1);
  1428.       }
  1429.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1430.       {
  1431.       gremlin_rocket1();
  1432.       OgreFireGrenade();
  1433.       self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1434.       SUB_AttackFinished(1);
  1435.       }
  1436.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1437.       {
  1438.       gremlin_rocket1();
  1439.       Gremlin_FireRocket();
  1440.       SUB_AttackFinished(1);
  1441.       }
  1442.     else if (self.weapon == IT_LIGHTNING)
  1443.       {
  1444.       gremlin_light1();
  1445.       SUB_AttackFinished(1);
  1446.       sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1447.       }
  1448.    else if (self.weapon == IT_LASER_CANNON)
  1449.       {
  1450.       gremlin_laser3();
  1451.       SUB_AttackFinished(1);
  1452.       }
  1453.    else if (self.weapon == IT_PROXIMITY_GUN)
  1454.       {
  1455.       gremlin_rocket1();
  1456.       GremlinFireProximityGrenade();
  1457.       SUB_AttackFinished(1);
  1458.       }
  1459.    return TRUE;
  1460.    };
  1461.  
  1462. void() Gremlin_MissileAttack =
  1463.    {
  1464.    if (self.stoleweapon)
  1465.       {
  1466.       if (GremlinWeaponAttack())
  1467.          return;
  1468.       else if ((random()<0.1) && (self.flags & FL_ONGROUND))
  1469.          {
  1470.          gremlin_jump1();
  1471.          return;
  1472.          }
  1473.       }
  1474.    if (self.flags & FL_ONGROUND)
  1475.       gremlin_jump1();
  1476.    };
  1477.  
  1478. /*QUAKED monster_gremlin (1 0 0) (-32 -32 -24) (32 32 64) Ambush
  1479.  
  1480. */
  1481. void() monster_gremlin =
  1482. {
  1483.    if (deathmatch)
  1484.     {
  1485.         remove(self);
  1486.         return;
  1487.     }
  1488.    NumGremlins = NumGremlins + 1;
  1489.    precache_model ("progs/grem.mdl");
  1490.    precache_model ("progs/h_grem.mdl");
  1491.  
  1492.    precache_sound ("grem/death.wav");
  1493.    precache_sound ("grem/attack.wav");
  1494.    precache_sound ("demon/djump.wav");
  1495.    precache_sound ("demon/dhit2.wav");
  1496.    precache_sound ("grem/pain1.wav");
  1497.    precache_sound ("grem/pain2.wav");
  1498.    precache_sound ("grem/pain3.wav");
  1499.    precache_sound ("grem/idle.wav");
  1500.    precache_sound ("grem/sight1.wav");
  1501.  
  1502.    self.solid = SOLID_SLIDEBOX;
  1503.     self.movetype = MOVETYPE_STEP;
  1504.  
  1505.    setmodel (self, "progs/grem.mdl");
  1506.  
  1507.    setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  1508.    self.health = 100;
  1509.    self.max_health = 101;
  1510.    self.yaw_speed = 40;
  1511.  
  1512.    self.th_stand = gremlin_stand1;
  1513.    self.th_walk = gremlin_walk1;
  1514.    self.th_run = gremlin_run1;
  1515.    self.th_die = gremlin_die;
  1516.    self.th_melee = Gremlin_MeleeAttack;     // one of two attacks
  1517.    self.th_missile = Gremlin_MissileAttack; // check for random jump or firing of weapon
  1518.    self.th_pain = gremlin_pain;
  1519.  
  1520.     walkmonster_start();
  1521. };
  1522.  
  1523. float()  GremlinCheckAttack =
  1524.    {
  1525.     local vector    spot1, spot2;
  1526.     local entity    targ;
  1527.     local float        chance;
  1528.  
  1529.     targ = self.enemy;
  1530.  
  1531.    if (time < self.attack_finished)
  1532.       return FALSE;
  1533.  
  1534. // see if any entities are in the way of the shot
  1535.    spot1 = self.origin;// + self.view_ofs;
  1536.    spot2 = targ.origin;// + targ.view_ofs;
  1537.  
  1538.    if ((vlen(spot2 - spot1) <= 90) && (self.stoleweapon == 0))
  1539.       {
  1540.       self.attack_state = AS_MELEE;
  1541.       return TRUE;
  1542.       }
  1543. // missile attack
  1544.    chance = 0.03 + self.stoleweapon;
  1545.    if (random() < chance)
  1546.       {
  1547.       self.attack_state = AS_MISSILE;
  1548.       return TRUE;
  1549.       }
  1550.     return FALSE;
  1551.    };
  1552.  
  1553.  
  1554. //===========================================================================
  1555.  
  1556. void(float side)  Gremlin_Melee =
  1557. {
  1558.     local    float    ldmg;
  1559.     local vector    delta;
  1560.  
  1561.     ai_face ();
  1562.  
  1563. //   walkmove (self.ideal_yaw, 12);   // allow a little closing
  1564.  
  1565.  
  1566.     delta = self.enemy.origin - self.origin;
  1567.  
  1568.     if (vlen(delta) > 100)
  1569.         return;
  1570.     if (!CanDamage (self.enemy, self))
  1571.         return;
  1572.  
  1573.     sound (self, CHAN_WEAPON, "grem/attack.wav", 1, ATTN_NORM);
  1574.     ldmg = 10 + 5*random();
  1575.     T_Damage (self.enemy, self, self, ldmg);
  1576.  
  1577.     makevectors (self.angles);
  1578.     SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
  1579. };
  1580.  
  1581. //===========================================================================
  1582. void(float dm) Gremlin_ThrowHead =
  1583.    {
  1584.    local string gibname;
  1585.    if (self.classname == "monster_ogre")
  1586.       gibname = "progs/h_ogre.mdl";
  1587.     else if (self.classname == "monster_knight")
  1588.       gibname = "progs/h_knight.mdl";
  1589.    else if (self.classname == "monster_shambler")
  1590.       gibname = "progs/h_shams.mdl";
  1591.    else if (self.classname == "monster_demon1")
  1592.       gibname = "progs/h_demon.mdl";
  1593.    else if (self.classname == "monster_wizard")
  1594.       gibname = "progs/h_wizard.mdl";
  1595.    else if (self.classname == "monster_zombie")
  1596.       gibname = "progs/h_zombie.mdl";
  1597.    else if (self.classname == "monster_dog")
  1598.       gibname = "progs/h_dog.mdl";
  1599.    else if (self.classname == "monster_hell_knight")
  1600.       gibname = "progs/h_hellkn.mdl";
  1601.    else if (self.classname == "monster_enforcer")
  1602.       gibname = "progs/h_mega.mdl";
  1603.    else if (self.classname == "monster_army")
  1604.       gibname = "progs/h_guard.mdl";
  1605.    else if (self.classname == "monster_shalrath")
  1606.       gibname = "progs/h_shal.mdl";
  1607.    else if (self.classname == "monster_gremlin")
  1608.       gibname = "progs/h_grem.mdl";
  1609.    else if (self.classname == "monster_scourge")
  1610.       gibname = "progs/h_scourg.mdl";
  1611.    else if (self.classname == "monster_fish")
  1612.       gibname = "progs/gib1.mdl";
  1613.    else
  1614.       gibname = "progs/h_player.mdl";
  1615.    ThrowHead(gibname,dm);
  1616.    };
  1617. //===========================================================================
  1618.  
  1619. /*
  1620. ============
  1621. Gremlin_Damage
  1622.  
  1623. The damage is coming from inflictor, but get mad at attacker
  1624. ============
  1625. */
  1626. void(entity targ, entity inflictor, entity attacker, float damage) Gremlin_Damage=
  1627. {
  1628. // check for godmode or invincibility
  1629.     if (targ.flags & FL_GODMODE)
  1630.         return;
  1631.     if (targ.invincible_finished >= time)
  1632.     {
  1633.         if (self.invincible_sound < time)
  1634.         {
  1635.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  1636.             self.invincible_sound = time + 2;
  1637.         }
  1638.         return;
  1639.     }
  1640.  
  1641. // team play damage avoidance
  1642.     if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  1643.         return;
  1644.  
  1645. // do the damage
  1646.    targ.health = targ.health - damage;
  1647.    };
  1648.  
  1649. void() Gremlin_Split =
  1650.    {
  1651.    local entity grem;
  1652.    local entity temp;
  1653.    local entity head;
  1654.    local float done;
  1655.    local vector ang;
  1656.    local float c;
  1657.    local vector pos;
  1658.    local float proceed;
  1659.  
  1660.    if (NumSpawnGremlins >= (NumGremlins*2))
  1661.       return;
  1662.    done = 0;
  1663.    c = 0;
  1664.    ang = self.angles;
  1665.    while (done == 0)
  1666.       {
  1667.       makevectors(ang);
  1668.       pos = self.origin + (80 * v_forward);
  1669.       head = findradius(pos, 35);
  1670.       proceed = 1;
  1671.       while (head)
  1672.          {
  1673.          if ((head.health > 0) && (head.flags & (FL_MONSTER | FL_CLIENT)))
  1674.             proceed = 0;
  1675.          head = head.chain;
  1676.          }
  1677.       traceline(self.origin,pos,FALSE,self);
  1678.       if (trace_fraction == 1 && (proceed == 1))
  1679.          {
  1680.          traceline(self.origin,(pos-'40 40 0'),FALSE,self);
  1681.          if (trace_fraction == 1)
  1682.             {
  1683.             traceline(self.origin,(pos+'40 40 0'),FALSE,self);
  1684.             if (trace_fraction == 1)
  1685.                {
  1686.                traceline(self.origin,(pos + '0 0 64'),FALSE,self);
  1687.                if (trace_fraction == 1)
  1688.                   {
  1689.                   traceline(self.origin,(pos - '0 0 64'),FALSE,self);
  1690.                   if (trace_fraction != 1)
  1691.                      {
  1692.                      done = 1;
  1693.                      }
  1694.                   }
  1695.                }
  1696.             }
  1697.          }
  1698.       if (done == 0)
  1699.          {
  1700.          ang_y = ang_y + 36;
  1701.          c = c + 1;
  1702.          if (c==10)
  1703.             {
  1704.             return;
  1705.             }
  1706.          }
  1707.       }
  1708.    NumSpawnGremlins = NumSpawnGremlins + 1;
  1709.    grem = spawn();
  1710.    SUB_CopyEntity(self,grem);
  1711.    grem.solid = SOLID_SLIDEBOX;
  1712.    grem.movetype = MOVETYPE_STEP;
  1713.    setmodel (grem, "progs/grem.mdl");
  1714.    setsize (grem, VEC_HULL_MIN, VEC_HULL_MAX);
  1715.    if (self.health < 100) self.health = 100;
  1716.    grem.health = self.health / 2;
  1717.    self.health = self.health / 2;
  1718. //   grem.max_health = 101;
  1719. //   grem.gorging = FALSE;
  1720.    grem.stoleweapon = FALSE;
  1721.    grem.items = 0;
  1722.    total_monsters = total_monsters + 1;
  1723.    WriteByte (MSG_BROADCAST, SVC_UPDATESTAT);
  1724.    WriteByte (MSG_BROADCAST, STAT_TOTALMONSTERS);
  1725.    WriteLong (MSG_BROADCAST, total_monsters);
  1726.    setorigin(grem, pos);
  1727.    temp = self;
  1728.    self = grem;
  1729.    gremlin_spawn1();
  1730.    self.enemy = world;
  1731.    self.gorging = FALSE;
  1732.    self = temp;
  1733.    };
  1734.  
  1735. void(float side)  Gremlin_Gorge =
  1736.    {
  1737.     local    float    ldmg;
  1738.     local vector    delta;
  1739.    local entity temp;
  1740.  
  1741. //   ai_face ();
  1742. //   walkmove (self.ideal_yaw, 6);   // allow a little closing
  1743.  
  1744.     delta = self.enemy.origin - self.origin;
  1745. //   self.enemy.takedamage = DAMAGE_YES;
  1746.  
  1747.     sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
  1748. //    sound (self, CHAN_WEAPON, "grem/attack.wav", 1, ATTN_NORM);
  1749.    ldmg = 7+5*random();
  1750.    Gremlin_Damage (self.enemy, self, self, ldmg);
  1751.  
  1752.     makevectors (self.angles);
  1753.     SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
  1754.    if (self.enemy.health < -200.0)
  1755.       {
  1756.       if (self.enemy.gorging==FALSE)
  1757.          {
  1758.          self.enemy.gorging = TRUE;
  1759.          sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
  1760.          temp = self;
  1761.          self = self.enemy;
  1762.          Gremlin_ThrowHead(-15);
  1763. //         ThrowGib ("progs/gib1.mdl", -15);
  1764. //         ThrowGib ("progs/gib2.mdl", -15);
  1765. //         ThrowGib ("progs/gib3.mdl", -15);
  1766.          self = temp;
  1767.          ldmg = 150 + 100*random();
  1768.          T_Heal(self,ldmg,FALSE);
  1769. //         if (self.health >= self.max_health)
  1770.             Gremlin_Split();
  1771.          }
  1772.       self.enemy = world;
  1773.       self.gorging = FALSE;
  1774. /*
  1775.       if (self.stoleweapon)
  1776.          {
  1777.          temp = GremlinFindVictim();
  1778.          if (temp != world)
  1779.             {
  1780.             self.enemy = temp;
  1781.             FoundTarget();
  1782.             self.search_time = time + 1.0;
  1783. //            return;
  1784.             }
  1785.          }
  1786. */
  1787. //      FindTarget();
  1788. /*
  1789.       if (self.oldenemy.health > 0)
  1790.          {
  1791.          self.enemy = self.oldenemy;
  1792.          HuntTarget ();
  1793.          }
  1794.       else
  1795.          {
  1796.          if (self.movetarget)
  1797.             self.th_walk ();
  1798.          else
  1799.             self.th_stand ();
  1800.          }
  1801. */
  1802.       gremlin_look1();
  1803.       }
  1804.    };
  1805.  
  1806.  
  1807. void()   Gremlin_JumpTouch =
  1808. {
  1809.     local    float    ldmg;
  1810.  
  1811.    if (self.health <= 0)
  1812.         return;
  1813.  
  1814. /*
  1815.     if (other.takedamage)
  1816.     {
  1817.         if ( vlen(self.velocity) > 400 )
  1818.         {
  1819.             ldmg = 40 + 10*random();
  1820.             T_Damage (other, self, self, ldmg);
  1821.         }
  1822.     }
  1823. */
  1824.     if (!checkbottom(self))
  1825.       {
  1826.         if (self.flags & FL_ONGROUND)
  1827.          {
  1828.          self.touch = SUB_Null;
  1829.          self.think = gremlin_jump1;
  1830.          self.nextthink = time + 0.1;
  1831.          }
  1832.         return;    // not on ground yet
  1833.       }
  1834.  
  1835.     self.touch = SUB_Null;
  1836.    self.think = gremlin_jump12;
  1837.     self.nextthink = time + 0.1;
  1838. };
  1839.  
  1840. void()   Gremlin_FlipTouch =
  1841. {
  1842.     local    float    ldmg;
  1843.  
  1844.     if (!checkbottom(self))
  1845.       {
  1846.         if (self.flags & FL_ONGROUND)
  1847.          {
  1848.          self.touch = SUB_Null;
  1849.          self.think = gremlin_flip1;
  1850.          self.nextthink = time + 0.1;
  1851.          }
  1852.         return;    // not on ground yet
  1853.       }
  1854.  
  1855.     self.touch = SUB_Null;
  1856.    self.think = gremlin_flip8;
  1857.     self.nextthink = time + 0.1;
  1858. };
  1859.